/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Model;

import java.util.*;

/**
 *
 * @author snowangelic
 */
class Centroid extends Action {

    Centroid(){

    }

    public void recomputePosition(ArrayList<Action> actionList,DataSet dataSet) {
         for(int i=0;i<dataSet.getAttributeNbr();i++){
            Attribute currentAttribute=dataSet.getAttribute(i);
            if(currentAttribute.getType()==AttributeType.Numerical){
                float attributeValue=0;
                for(int j=0;j<actionList.size();j++){
                        attributeValue=attributeValue+(Float) actionList.get(j).getValue(currentAttribute,false);
                }
                attributeValue=attributeValue/actionList.size();
                this.setValue(currentAttribute,attributeValue);
            }
            else if(currentAttribute.getType()==AttributeType.TextualDiscreet){
                ArrayList<String> strList=new ArrayList<String>();
                for(int j=0;j<actionList.size();j++){
                        strList.add((String)actionList.get(j).getValue(currentAttribute,false));
                }
                this.setValue(currentAttribute,strList);
            }
         }
         for(int i=0;i<dataSet.getAttributeNbr();i++){
            Attribute currentAttribute=dataSet.getAttribute(i);
            if(currentAttribute.getType()==AttributeType.Numerical){
                float attributeValue=0;
                for(int j=0;j<actionList.size();j++){
                        attributeValue=attributeValue+(Float) actionList.get(j).getValue(currentAttribute,true);
                }
                attributeValue=attributeValue/actionList.size();
                setNormalizedValue(currentAttribute,attributeValue);
            }
            else if(currentAttribute.getType()==AttributeType.TextualDiscreet){
                ArrayList<String> strList=new ArrayList<String>();
                for(int j=0;j<actionList.size();j++){
                        strList.add((String)actionList.get(j).getValue(currentAttribute,true));
                }
                setNormalizedValue(currentAttribute,strList);
            }
            else {System.out.println("INCORRECT ATTRBUTE TYPE");}
         }
    }

    public float getDistanceFromAction(Action action ,ArrayList<Weight> weightList,boolean normalized,Distance distance){
        if(distance==Distance.EUCLIDIAN){
            float count=0;
            float subCount=0;
            
            for(int k=0;k<weightList.size();k++){
                float attributeDistance=0;
                Weight currentWeight=weightList.get(k);
                if(currentWeight.getAttribute().getType()==AttributeType.TextualDiscreet){
                    ArrayList<String> centroidStringList=(ArrayList<String>)this.getValue(currentWeight.getAttribute(),normalized);
                    if(action.getClass().equals(this.getClass())){
                        String actionString=(String)action.getValue(currentWeight.getAttribute(),normalized);

                        // On compte le nombre de fois que le String de l'action se trouve Dans notre liste de String
                        int stringInListCount=0;
                        for(int i=0;i<centroidStringList.size();i++){
                            if(centroidStringList.get(i).equals(actionString)) stringInListCount++;
                        }
                        // La distance maximum est 100 et la distance minimum est 0
                        attributeDistance= 100-(100*stringInListCount/centroidStringList.size());
                    }
                    else{
                        ArrayList<String> actionStringList=(ArrayList<String>)action.getValue(currentWeight.getAttribute(),normalized);
                        for(int j=0;j<actionStringList.size();j++){
                            String actionString=actionStringList.get(j);
                            // On compte le nombre de fois que le String de l'action se trouve Dans notre liste de String
                            int stringInListCount=0;
                            for(int i=0;i<centroidStringList.size();i++){
                                if(centroidStringList.get(i).equals(actionString)) stringInListCount++;
                            }
                            // La distance maximum est 100 et la distance minimum est 0
                            attributeDistance=attributeDistance+100-(100*stringInListCount/centroidStringList.size());
                        }
                        attributeDistance=attributeDistance/actionStringList.size();
                    }
                }
                else if(currentWeight.getAttribute().getType()==AttributeType.Numerical){
                    attributeDistance=(((Float)this.getValue(currentWeight.getAttribute(),normalized) - (Float)action.getValue(currentWeight.getAttribute(),normalized)));             
                }
                else{ System.out.println("Distance not yet implemeted for this Attribute Type"); }
                subCount=attributeDistance*attributeDistance*currentWeight.getWeight();
                count=count+subCount;
            }
            return (float) Math.sqrt(count);

        }
        else if(distance==Distance.MANHATTAN){
            float count=0;
            float subCount=0;
            float attributeDistance=0;

            for(int k=0;k<weightList.size();k++){
                Weight currentWeight=weightList.get(k);
                if(currentWeight.getAttribute().getType()==AttributeType.TextualDiscreet){
                    System.out.println(""+k+" ieme attribut de la weightList sur "+weightList.size()+" est textuel et son nom est "+currentWeight.getAttribute().getName());
                    ArrayList<String> centroidStringList=(ArrayList<String>)this.getValue(currentWeight.getAttribute(),normalized);
                    String actionString=(String)action.getValue(currentWeight.getAttribute(),normalized);

                    // On compte le nombre de fois que le String de l'action se trouve Dans notre liste de String
                    int stringInListCount=0;
                    for(int i=0;i<centroidStringList.size();i++){
                        if(centroidStringList.get(i).equals(actionString)) stringInListCount++;
                    }
                    // La distance maximum est 100 et la distance minimum est 0
                    attributeDistance= 100-(100*stringInListCount/centroidStringList.size());
                }
                else if(currentWeight.getAttribute().getType()==AttributeType.Numerical){
                    attributeDistance=(((Float)this.getValue(currentWeight.getAttribute(),normalized) - (Float)action.getValue(currentWeight.getAttribute(),normalized)));
                }
                else{ System.out.println("Distance not yet implemeted for this Attribute Type"); }
                subCount=attributeDistance*currentWeight.getWeight();
                count=count+subCount;
            }
            return (float) count;
        }
        else if(distance==Distance.TCHEBYSHEV){
            float max=0;
            float subCount=0;
            float attributeDistance=0;

            for(int k=0;k<weightList.size();k++){
                Weight currentWeight=weightList.get(k);
                if(currentWeight.getAttribute().getType()==AttributeType.TextualDiscreet){
                    ArrayList<String> centroidStringList=(ArrayList<String>)this.getValue(currentWeight.getAttribute(),normalized);
                    String actionString=(String)action.getValue(currentWeight.getAttribute(),normalized);

                    // On compte le nombre de fois que le String de l'action se trouve Dans notre liste de String
                    int stringInListCount=0;
                    for(int i=0;i<centroidStringList.size();i++){
                        if(centroidStringList.get(i).equals(actionString)) stringInListCount++;
                    }
                    // La distance maximum est 100 et la distance minimum est 0
                    attributeDistance= 100-(100*stringInListCount/centroidStringList.size());
                }
                else if(currentWeight.getAttribute().getType()==AttributeType.Numerical){
                    attributeDistance=(((Float)this.getValue(currentWeight.getAttribute(),normalized) - (Float)action.getValue(currentWeight.getAttribute(),normalized)));
                }
                else{ System.out.println("Distance not yet implemeted for this Attribute Type"); }
                if(attributeDistance>max)max=attributeDistance;
            }
            return (float) max;
        }
        else{
            System.out.println("===> ERROR : Wrong Distance <===");
            return 0;
        }
    }

    float getDistanceFromCluster(Cluster cluster, ArrayList<Weight> weightList, boolean normalized, Distance distance) {
        Centroid centro=cluster.getCentroid();
        return getDistanceFromAction(centro,weightList,normalized,distance);
    }
}
